﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using StockShark.Models;
using StockShark.BusinessModels;
using System.Web.Security;

namespace StockShark.Controllers
{ 
    public class OrderController : Controller
    {
        private StockSharkDB db = new StockSharkDB();

        public ActionResult ExecuteNow()
        {
            TradeCenter.ExecuteTransactions(true, true, true, true);
            return RedirectToAction("Index", "Home");
        }

        public ActionResult BuyList(string account)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            try
            {
                ba = accountList.Single(r => r.Name == account);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            ViewBag.BrokerageAccount = ba;
            ViewBag.TypeList = new string[] {"Wszystko", "Akcje - Rynek Główny", "Akcje - NewConnect", "Waluty", "Surowce"};
            var instrumentList = db.Instruments.ToList().Where(r => r.GetType().Name != "Index");
            return View(instrumentList);
        }

        public ActionResult SellList(string account)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            try
            {
                ba = accountList.Single(r => r.Name == account);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            ViewBag.BrokerageAccount = ba;
            ViewBag.TypeList = new string[] { "Wszystko", "Akcje - Rynek Główny", "Akcje - NewConnect", "Waluty", "Surowce" };
            var instrumentList = ba.OwnedInstruments;
            return View(instrumentList);
        }

        [HttpGet]
        public ActionResult Buy(string account, int item)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            Instrument instr;
            try
            {
                ba = accountList.Single(r => r.Name == account);
                instr = db.Instruments.Find(item);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            var order = new Order { BrokerageAccount = ba, Paper = instr, PaperId = item, Deadline = DateTime.Today.AddDays(3) };
            return View(order);
        }

        [HttpPost]
        public ActionResult Buy(Order order, string account)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            Instrument instr;
            try
            {
                ba = accountList.Single(r => r.Name == account);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            order.BrokerageAccount = ba;
            order.BuyNotSell = true;
            order.IssuingDate = DateTime.Now;
            order.Paper = db.Instruments.Find(order.PaperId);
            if (ModelState.IsValid)
            {
                db.Orders.Add(order);
                db.SaveChanges();
                return RedirectToAction("Orders", "BrokerageAccount", new { name = ba.Name });
            }
            return View(order);
        }

        [HttpGet]
        public ActionResult Sell(string account, int item)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            OwnedInstrument owned;
            try
            {
                ba = accountList.Single(r => r.Name == account);
                owned = db.OwnedInstruments.Single(r => r.PaperId == item);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            ViewBag.Owned = owned.Quantity;
            var order = new Order { BrokerageAccount = ba, Paper = owned.Paper, PaperId = item, Deadline = DateTime.Today.AddDays(3) };
            return View(order);
        }

        [HttpPost]
        public ActionResult Sell(Order order, string account)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            OwnedInstrument owned;
            try
            {
                ba = accountList.Single(r => r.Name == account);
                owned = db.OwnedInstruments.Single(r => r.PaperId == order.PaperId);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            order.BrokerageAccount = ba;
            order.BuyNotSell = false;
            order.IssuingDate = DateTime.Now;
            order.Paper = db.Instruments.Find(order.PaperId);
            if (owned.Quantity < order.Quantity)
                ModelState.AddModelError("Quantity", "Nie Posiadasz takiej ilości walorów na tym rachunku");
            if (ModelState.IsValid)
            {
                db.Orders.Add(order);
                db.SaveChanges();
                return RedirectToAction("Orders", "BrokerageAccount", new { name = ba.Name });
            }
            ViewBag.Owned = owned.Quantity;
            return View(order);
        }

        public ActionResult Cancel(int id)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            Order order;
            try
            {
                order = db.Orders.Find(id);
                ba = accountList.Single(r => r.Name == order.BrokerageAccount.Name);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            return View(order);
        }

        [HttpPost, ActionName("Cancel")]
        public ActionResult CancelConfirmed(int id)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            Order order;
            try
            {
                order = db.Orders.Find(id);
                ba = accountList.Single(r => r.Name == order.BrokerageAccount.Name);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            db.Orders.Remove(order);
            db.SaveChanges();
            return RedirectToAction("Orders", "BrokerageAccount", new { name = ba.Name });
        }

        private List<BrokerageAccount> GetAccountsForCurrentUser()
        {
            if (Request.IsAuthenticated)
            {
                Guid userId = (Guid)Membership.GetUser().ProviderUserKey;
                return db.BrokerageAccounts.Where(r => r.UserId == userId).ToList();
            }
            else
                return null;
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}